package krypto.blindsignature.signer;

import java.math.BigInteger;
import java.security.SecureRandom;

import org.apache.log4j.Logger;


/**
 * 
 * <br>Klasa udostępniająca klucz publiczny i podpisywanie wiadomości, oparta o algorytm RSA</br>
 * @see sign
 *
 */
public class RSASigner {

	Logger log = Logger.getLogger(RSASigner.class);

	private final static BigInteger one = new BigInteger("1");
	private final static SecureRandom random = new SecureRandom();
	private final static int N = 1024;

	private BigInteger privateKey;
	private BigInteger publicKey;
	private BigInteger modulus;


	private static RSASigner e;
	
	
	private RSASigner() {
		BigInteger p = BigInteger.probablePrime(N / 2, random);
		BigInteger q = BigInteger.probablePrime(N / 2, random);
		BigInteger phi = (p.subtract(one)).multiply(q.subtract(one));

		log.info("p: " + p + " q: " + q + " phi: " + phi);
		modulus = p.multiply(q);
		publicKey = new BigInteger("65537");
		privateKey = publicKey.modInverse(phi);

		log.debug("public key: " + publicKey);
		log.debug("private key" + privateKey);

	}
	
	/**
	 * 
	 * Podpisanie wiadomości
	 * <br>message<sup>privateKey</sup></br>
	 * 
	 */
	public BigInteger sign(BigInteger message) {
		return message.modPow(privateKey, modulus);
	}


	public static RSASigner getInstance() {
		if (e == null) {
			e = new RSASigner();
			return e;
		} else {
			return e;
		}
	}

	public BigInteger getPublicKey() {
		return publicKey;
	}

	public void setPublicKey(BigInteger publicKey) {
		this.publicKey = publicKey;
	}

	public BigInteger getModulus() {
		return modulus;
	}

	public void setModulus(BigInteger modulus) {
		this.modulus = modulus;
	}
	
	

}
